home *** CD-ROM | disk | FTP | other *** search
- /**********************************************************************
- *
- * undel -- a file undelete utility
- *
- * Written in GNU c by Trevor Blight, Jan 93
- *
- * Portions of this program are based (loosely) on the program RESCUE2,
- * published in "The MS-DOS Developer's Guide", 2nd ed., by Howard W. Sams & Co.
- *
- * This software may be used freely for any purpose whatsoever.
- * Please enhance and return it to the public domain.
- *
- ***********************************************************************/
-
- #include <osbind.h>
- #include <aesbind.h>
- #include <vdibind.h>
- #include <gemfast.h>
- #include <string.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <ctype.h>
- #include <errno.h>
- #include <assert.h>
- #include "undel.h"
-
-
- #define MAX_CLUSTERS 4078 /* max nr clusters for 12 bit FAT */
- #define CHAIN_END 1 /* used by get_cluster() to indicate eof */
-
- typedef unsigned char BYTE;
- typedef unsigned short WORD;
- typedef unsigned long LONG;
-
-
- typedef struct {
- char name[8]; /* name */
- char ext[3]; /* extension */
- BYTE attrib; /* attribute */
- BYTE reserved[10];
- WORD time; /* time: hhhhh mmm - mmm sssss */
- WORD date; /* date: yyyyyyy m - mmm ddddd */
- WORD cluster; /* starting cluster (Intel format) */
- LONG fsize; /* total size in bytes (Intel format) */
- } DENTRY;
-
-
- BYTE *FatBuffer; /* FAT table buffer address */
- DENTRY *dirBuffer; /* directory buffer address */
- DENTRY *dirend;
- int wi_handle; /* window handle */
-
- /*** forward declarations ***/
-
- PRIVATE void win_tidy( void );
- PRIVATE BOOL fill_dta( WORD srch_att );
- PRIVATE void undelete_file( const char *pathp );
- PRIVATE WORD next_cluster( const WORD clust );
- PRIVATE BOOL match( const char *sname, const char *fname );
- PRIVATE WORD swap_word( const WORD word );
- PRIVATE LONG swap_long( const LONG l );
- PRIVATE void fnmcpy( char* d, const char *s );
- PRIVATE int find_subdir( WORD dnum, const char *pathp, WORD *snump );
-
-
- /*** sector <--> cluster conversion macros ***/
- #define sector_of(cl) ((cl - 2)*bpbp->clsiz + bpbp->datrec)
- #define cluster_of(s) (2 + (s - bpbp->datrec)/bpbp->clsiz)
-
-
- /********************************************************
- *
- * call this function at end of program to tidy up AES windows
- *
- *******************************************************/
-
- PRIVATE void win_tidy( void )
- {
- wind_close(wi_handle);
- wind_delete(wi_handle);
- appl_exit();
- } /* win_tidy() */
-
-
- /*********************************************************
- *
- * main entry point
- *
- *********************************************************/
-
- int main(void) /* ignore params */
- {
-
- #define WI_KIND 0
-
- char dname[80]; /* directory name buffer */
- int dnum; /* drive nr, A: = 0, etc */
- int r; /* fsel return value */
- int sextn;
- char fname[64];
- int xdesk,ydesk,hdesk,wdesk;
- char extn3str[4];
- char extn4str[4];
-
- appl_init();
- wind_get(0, WF_WORKXYWH, &xdesk, &ydesk, &wdesk, &hdesk);
- wi_handle = wind_create(WI_KIND, xdesk, ydesk, wdesk, hdesk);
- if( wi_handle < 0 ) {
- form_alert(1, "[1][too many windows open][QUIT]" );
- appl_exit();
- exit(1); /* quit */
- } /* if */
- wind_open(wi_handle,xdesk,ydesk,wdesk,hdesk);
- if (atexit(win_tidy) != 0 ) {
- form_alert(1, "[1][can't arrange tidy up at exit][QUIT]" );
- win_tidy();
- exit(1);
- } /* if */
-
- graf_mouse(ARROW, 0x0L);
- strcpy (dname, "\\");
- dnum = -1;
- sextn = 0x0001; /* select extension 1 */
- strcpy( extn3str, "c " );
- strcpy( extn4str, "h " );
- r = fsel("Select a file to undelete ...", /* I display title for box */
- dname, /* IO initial path spec \ ... \ no drive; returns selected path */
- &dnum, /* IO selects drive -1=default 0=A: .. 5=F: */
- &sextn, /* IO bitmap selected extn boxes :
- * 0x0001 = extn0 0x0002 = extn1 0x0004 = extn2
- * 0x0008 = extn3 0x0010 = extn4
- */
- "* ", /* I extension text not including "." for each of 1st 3 extn boxes */
- "PRG", /* NOTE for all 5 boxes this should be 3 chars long, even if spaces */
- "DOC",
- extn3str,
- extn4str, /* IO extension text for last 2 extn boxes (editable) */
- fname); /* O returns complete path and file */
-
-
- if (r != 0) {
- undelete_file( fname );
- } /* if */
-
- return 0; /* successful completion */
-
- } /* main */
-
-
- /********************************************************
- *
- * replacement for Fsfirst() & Fsnext() to recognise deleted files
- *
- ********************************************************/
-
- struct BPB {
- short recsiz; /* physical sector size in bytes */
- short clsiz; /* cluster size in sectors */
- short clsizb; /* cluster size in bytes */
- short rdlen; /* root directory length in sectors */
- short fsiz; /* FAT size in sectors */
- short fatrec; /* second FAT starts at this sector */
- short datrec; /* data sectors start here */
- short numcl; /* nr of data clusters on disk */
- short bflags; /* flags */
- };
-
- /*** custom dta buffer for d_First() & d_Next() ***/
- struct DTA {
- WORD dta_sector;
- DENTRY *dta_dirBuffer;
- DENTRY *dta_entryp;
- DENTRY *dta_dirend;
- unsigned short dta_srchattr;
- char dta_buf[4];
- char dta_drv;
- char dta_attribute;
- unsigned short dta_time;
- unsigned short dta_date;
- long dta_size;
- char dta_name[14];
- };
-
- PRIVATE struct BPB *bpbp;
- PRIVATE struct DTA *dtap;
-
- short d_First(char *drvp, char *pathp, short attr)
- {
- WORD dnum; /* drive nr, A: = 0, etc */
- int error;
- WORD snum; /* sector number */
-
- dnum = toupper(*drvp) - 'A';
- if( (Drvmap() & (1 << dnum)) == 0 ) {
- return ENXIO;
- } /* if */
-
- if( *pathp == '\\' ) {
- pathp++;
- } /* if */
-
- /*** get FAT size, root directory sector, etc from Bios Parameter Block... ***/
- if( (bpbp = (struct BPB *)Getbpb(dnum)) == 0 ) {
- char emsg[80];
- sprintf( emsg, "[1][can't get parameters for drive %c:][QUIT]", 'A'+dnum);
- form_alert(1, emsg );
- exit(1); /* quit */
- } /* if */
-
- /*** allocate memory for directory buffers & FAT tables ***/
-
- if( ((dirBuffer = (DENTRY *)malloc(bpbp->clsizb)) == NULL
- OR (FatBuffer = (BYTE *)malloc(bpbp->fsiz * bpbp->recsiz)) == NULL) )
- {
- form_alert(1, "[1][can't allocate enough memory][QUIT]" );
- exit(1); /* quit */
- } /* if */
-
- dirend = &dirBuffer[bpbp->clsizb/sizeof(*dirBuffer)];
-
- /*** read in FAT ***/
-
- error = Rwabs( 0 /* read mode */, FatBuffer, bpbp->fsiz,
- bpbp->fatrec - bpbp->fsiz, /* first FAT starts here */
- dnum );
- if (error != 0) {
- char emsg[80];
- sprintf( emsg, "[1][%s|while reading FAT on drive %c][QUIT]",
- strerror(-error), dnum + 'A' );
- form_alert(1, emsg);
- exit(1); /* quit */
- } /* if */
-
- if( (error = find_subdir( dnum, pathp, &snum )) != 0 )
- {
- return error;
- } /* if */
-
- if( (attr & FA_DIR) == 0 ) {
- char emsg[80];
- sprintf( emsg, "[1][path is not a directory:|%s][QUIT]", pathp );
- form_alert(1, emsg);
- exit(1); /* quit */
- } /* if */
-
- /*******************************************************
- *
- * snum is the sector which has the directory entries
- *
- *******************************************************/
-
- error = Rwabs( 0 /* read mode */, dirBuffer, bpbp->clsiz, snum, dnum );
- if (error != 0) {
- char emsg[80];
- sprintf( emsg, "[1][%s|while reading|directory entries on drive %c][QUIT]",
- strerror(-error), dnum + 'A' );
- form_alert(1, emsg);
- exit(1); /* quit */
- } /* if */
-
- /*** fill the dta buffer with the first directory entry in dirBuffer ***/
-
- dtap = (struct DTA *)Fgetdta();
-
- dtap->dta_sector = snum;
- dtap->dta_dirBuffer = dirBuffer;
- dtap->dta_entryp = dirBuffer;
- dtap->dta_dirend = dirend;
- dtap->dta_drv = dnum;
-
- return fill_dta(0) ? 0 : -ENOENT;
-
- } /* d_First() */
-
-
- short d_Next()
- {
- return fill_dta(0) ? 0 : -ENMFILES; /* OK ? */
- } /* d_Next() */
-
-
- /*************************************************************
- *
- * copy next subdirectory entry into dta
- *
- *************************************************************/
-
- PRIVATE BOOL fill_dta( WORD srch_att )
- {
- DENTRY *dptr; /* current directory entry */
- WORD cluster;
- int error;
- struct DTA *dtap;
-
- dtap = (struct DTA *)Fgetdta();
- dptr = dtap->dta_entryp++;
-
- if( dptr >= dtap->dta_dirend ) {
-
- /*** all entries in this cluster exhausted, get next cluster ***/
-
- if( dtap->dta_sector >= bpbp->datrec ) {
- /*** this is a subdirectory ***/
- cluster = cluster_of( dtap->dta_sector );
- if( (cluster = next_cluster( cluster )) <= CHAIN_END ) {
- return( FALSE ); /* no more files */
- }
- else {
- dtap->dta_sector = sector_of( cluster );
- } /* if */
- }
- else if( dtap->dta_sector >= bpbp->fatrec + bpbp->fsiz ) {
- /*** this is the root directory ***/
- dtap->dta_sector += bpbp->clsiz; /* next cluster in root dir */
- if( dtap->dta_sector >= bpbp->datrec ) {
- return( FALSE ); /* no more files */
- } /* if */
- }
- else {
- /*** this shouldn't happen ***/
- char emsg[80];
- sprintf( emsg, "[1][error while reading FAT on drive %c][QUIT]",
- dtap->dta_drv + 'A' );
- form_alert(1, emsg);
- exit(1); /* quit */
- } /* if */
-
- error = Rwabs( 0 /* read mode */, dtap->dta_dirBuffer,
- bpbp->clsiz, dtap->dta_sector, dtap->dta_drv );
- if (error != 0) {
- char emsg[80];
- sprintf( emsg, "[1][%s|while reading|directory entries on drive %c][QUIT]",
- strerror(-error), dtap->dta_drv + 'A' );
- form_alert(1, emsg);
- exit(1); /* quit */
- } /* if */
- dtap->dta_entryp = dtap->dta_dirBuffer;
- dptr = dtap->dta_entryp++;
- } /* if */
-
- if( dptr->name[0] == '\0' ) {
- return( FALSE ); /* no more files */
- } /* if */
-
- dtap->dta_attribute = dptr->attrib;
- dtap->dta_time = dptr->time;
- dtap->dta_date = dptr->date;
- dtap->dta_size = dptr->fsize;
- fnmcpy( dtap->dta_name, dptr->name );
- assert( strlen(dtap->dta_name) < sizeof(dtap->dta_name) ); /* in case overflow */
-
- return TRUE;
-
- } /* fill_dta() */
-
-
- /*************************************************************
- *
- * find the first sector for a pathname
- * (the sector contains the subdirectory list)
- *
- **************************************************************/
-
- PRIVATE int find_subdir( WORD dnum, const char *pathp, WORD *snump )
- {
- WORD snum;
- WORD attr;
- WORD cluster;
- int error;
- DENTRY *dptr; /* current directory entry */
-
- /*** follow the chain of directory entries to match path name ***/
-
- snum = bpbp->fatrec + bpbp->fsiz; /* root directory starts here */
-
- if( *pathp == '\\' ) {
- pathp++;
- } /* if */
- while( *pathp != '\0' ) { /* loop thru all subdirectories in the path */
-
- error = Rwabs( 0 /* read mode */, dirBuffer, bpbp->clsiz, snum, dnum );
- if (error != 0) {
- char emsg[80];
- sprintf( emsg, "[1][%s|while reading|directory entries on drive %c][QUIT]",
- strerror(-error), dnum + 'A' );
- form_alert(1, emsg);
- exit(1); /* quit */
- } /* if */
- dptr = dirBuffer;
-
- /*** loop thru all directory entries until the name is found ***/
-
- while( ((dptr->attrib & FA_DIR) == 0) /* not a directory ? */
- OR NOT match( pathp, dptr->name ) ) { /* names don't match ? */
-
- if( ++dptr >= dirend ) {
-
- /*** name not found in this cluster, get next cluster ***/
-
- if( snum >= bpbp->datrec ) {
- /*** this is a subdirectory ***/
- cluster = cluster_of( snum );
- if( (cluster = next_cluster( cluster )) <= CHAIN_END ) {
- return( -EPATH ); /* path not found */
- }
- else {
- snum = sector_of( cluster );
- } /* if */
- }
- else if( snum >= bpbp->fatrec + bpbp->fsiz ) {
- /*** this is the root directory ***/
- snum += bpbp->clsiz; /* next cluster in root dir */
- if( snum >= bpbp->datrec ) {
- return( -EPATH ); /* path not found */
- } /* if */
- }
- else {
- /*** this shouldn't happen ***/
- char emsg[80];
- sprintf( emsg, "[1][error while reading|directory on drive %c][QUIT]",
- dnum + 'A' );
- form_alert(1, emsg);
- exit(1); /* quit */
- } /* if */
-
- error = Rwabs( 0 /* read mode */, dirBuffer, bpbp->clsiz, snum, dnum );
- if (error != 0) {
- char emsg[80];
- sprintf( emsg, "[1][%s|while reading|directory entries on drive %c][QUIT]",
- strerror(-error), dnum + 'A' );
- form_alert(1, emsg);
- exit(1); /* quit */
- } /* if */
-
- dptr = dirBuffer;
- } /* if */
-
- } /* while */
-
- /*** the next subdirectory name has been found ***/
-
- snum = sector_of( swap_word(dptr->cluster) );
- attr = dptr->attrib;
- while( (*pathp != '\0') AND (*pathp != '\\') ) {
- pathp++;
- } /* while */
- if( *pathp == '\\' ) {
- pathp++;
- } /* if */
- } /* while */
-
- *snump = snum;
- return 0;
-
- } /* find_subdir() */
-
-
- /**************************************************************
- *
- * undelete_file
- * pathp -- points to full pathname of file
- * eg A:\..dir_path..\file_name
- *
- * - find the directory entry of the file
- * - assume the file contents are in the empty clusters following the starting
- * cluster of the file.
- * - build an image of the file in data_buffer
- * - write out data_buffer to a new file
- *
- ***************************************************************/
-
- PRIVATE void undelete_file( const char *pathp )
- {
- WORD snum; /* sector number of directory entry */
- WORD dnum; /* disk drive number */
- WORD cluster;
- WORD current; /* current cluster in chain of deleted file */
- WORD previous; /* unused ??? */
- unsigned nrcl; /* number of clusters in deleted file */
- void *data_buffer; /* put copy of restored file here */
- void *datap; /* points into data_buffer */
- int i;
- int error; /* error return code for various functions */
- char fname[13]; /* name of file to be undeleted */
- char dir_path[80]; /* directory path of file to be undeleted */
- long file_size; /* size of the file */
- DENTRY *dptr; /* points to a copy of the directory entry of file */
- int fh; /* file handle for restored copy of file */
- char restored_fn[80]; /* name of restored file */
- char Path[80]; /* used for fsel_input() */
- int ExitButton; /* used for fsel_input() */
- long bytes_written; /* returned by Fwrite() */
-
- assert( pathp[1] == ':' );
- dnum = toupper(*pathp) - 'A';
- if( (Drvmap() & (1 << dnum)) == 0 ) {
- char emsg[80];
- sprintf( emsg, "[1][drive %c: doesn't exist!][QUIT]", *pathp );
- form_alert(1, emsg );
- exit(1); /* quit */
- } /* if */
-
- /*** split pathp into directory path & filename path ***/
- strcpy (dir_path, pathp+2);
- i = strlen( dir_path );
- while( i >= 0 ) {
- if( dir_path[i] == '\\' ) {
- strcpy(fname, dir_path+i+1);
- dir_path[i+1] = '\0';
- break;
- } /* if */
- i--;
- } /* while */
-
- if( find_subdir( dnum, dir_path, &snum ) != 0 ) {
- char emsg[80];
- sprintf( emsg, "[1][can't find file|%s][QUIT]", fname);
- form_alert(1, emsg );
- exit(1); /* quit */
- } /* if */
-
-
- /*** look for file name in directory sector ***/
-
- if (Rwabs( 0 /* read mode */, dirBuffer, bpbp->clsiz, snum, dnum ) != 0) {
- char emsg[80];
- sprintf( emsg, "[1][%s|while reading|directory entries on drive %c][QUIT]",
- strerror(-error), dtap->dta_drv + 'A' );
- form_alert(1, emsg);
- exit(1); /* quit */
- } /* if */
- dptr = dirBuffer;
-
- while( NOT match( fname, dptr->name ) ) {
-
- dptr++; /* point to next name */
- if( dptr >= dirend ) {
-
- /*** all entries in this cluster exhausted, get next cluster ***/
-
- if( snum >= bpbp->datrec ) {
- /*** this is a subdirectory ***/
- cluster = cluster_of( snum );
- if( (cluster = next_cluster( cluster )) <= CHAIN_END ) {
- char emsg[80];
- sprintf( emsg, "[1][can't find file|\"%s\"][QUIT]", fname);
- form_alert(1, emsg );
- exit(1); /* quit */
- }
- else {
- snum = sector_of( cluster );
- } /* if */
- }
- else if( snum >= bpbp->fatrec + bpbp->fsiz ) {
- /*** this is the root directory ***/
- snum += bpbp->clsiz; /* next cluster in root dir */
- if( snum >= bpbp->datrec ) {
- char emsg[80];
- sprintf( emsg, "[1][can't find file|\"%s\"][QUIT]", fname);
- form_alert(1, emsg );
- exit(1); /* quit */
- } /* if */
- }
- else {
- /*** this shouldn't happen ***/
- char emsg[80];
- sprintf( emsg, "[1][error while reading|root directory on drive %c][QUIT]",
- dnum + 'A' );
- form_alert(1, emsg);
- exit(1); /* quit */
- } /* if */
-
- if (Rwabs(0 /* read mode */, dirBuffer, bpbp->clsiz, snum, dnum) != 0) {
- char emsg[80];
- sprintf( emsg, "[1][%s|while reading|directory entries on drive %c][QUIT]",
- strerror(-error), dtap->dta_drv + 'A' );
- form_alert(1, emsg);
- exit(1); /* quit */
- } /* if */
- dptr = dirBuffer;
- } /* if */
-
- if( dptr->name[0] == '\0' ) {
- char emsg[80];
- sprintf( emsg, "[1][can't find file|\"%s\"][QUIT]", fname);
- form_alert(1, emsg );
- exit(1); /* quit */
- } /* if */
- } /* while */
-
-
- /********************************************************
- *
- * found the file to be undeleted:
- * - dptr points to a copy of the directory entry
- *
- ********************************************************/
-
- if( (char)dptr->name[0] != (char)0xe5) {
- char emsg[80];
- sprintf( emsg, "[1][file is not deleted|\"%s\"][QUIT]", pathp);
- form_alert(1, emsg );
- exit(1); /* quit */
- } /* if */
-
- current = previous = swap_word(dptr->cluster);
- if( next_cluster(current) != 0 ) {
- char emsg[80];
- sprintf( emsg, "[1][\"%s\"|has been overwritten][QUIT]", pathp);
- form_alert(1, emsg );
- exit(1); /* quit */
- } /* if */
-
- if( dptr->attrib == FA_DIR ) {
- nrcl = 0; /* directories have file size = 0 */
- }
- else {
- file_size = swap_long(dptr->fsize);
- nrcl = (file_size + bpbp->clsizb - 1)/bpbp->clsizb;
- } /* if */
-
- if( (datap = data_buffer = malloc( nrcl*bpbp->clsizb )) == NULL ) {
- form_alert(1, "[1][can't allocate enough memory][QUIT]" );
- exit(1); /* quit */
- } /* if */
-
- while( nrcl > 0 ) {
- if( current > bpbp->numcl ) {
- char emsg[80];
- sprintf( emsg, "[1][can't recover all of|\"%s\"][Carry On][QUIT]", pathp );
- if( form_alert(1, emsg ) == 2 ) {
- exit(1); /* quit */
- } /* if */
- file_size = (datap-data_buffer)*sizeof(*datap);
- } /* if */
- if( next_cluster( current ) == 0 ) {
- error = Rwabs( 0 /* read mode */, datap, bpbp->clsiz, sector_of(current), dnum );
- if (error != 0) {
- char emsg[80];
- sprintf( emsg, "[1][%s|while reading|file sectors on drive %c][QUIT]",
- strerror(-error), dtap->dta_drv + 'A' );
- form_alert(1, emsg);
- exit(1); /* quit */
- } /* if */
- datap += bpbp->clsizb;
- previous = current;
- nrcl--;
- } /* if */
- current++;
- } /* while */
-
- /*** now write the file out ***/
-
- strcpy(Path, "A:\\*.*");
- Path[0] += Dgetdrv();
- if( fsel_input(Path, restored_fn, &ExitButton) == 0 )
- {
- form_alert(1, "[1]can't select a name|for restored file[oh dear]");
- } /* if */
- if( ExitButton == 0 )
- {
- /* user has cancelled !!! */
- exit(1);
- } /* if */
-
- /*** merge Path & restored file name ***/
- i = strlen( Path );
- while( i >= 0 ) {
- if( Path[i] == '\\' ) {
- strcpy(Path+i+1, restored_fn);
- strcpy(restored_fn, Path);
- break;
- } /* if */
- i--;
- } /* while */
-
-
- if( (fh = Fopen( restored_fn, 1)) < 0 ) {
- if( fh != -ENOENT ) {
- char emsg[80];
- sprintf( emsg, "[1][%s|while opening %s][QUIT]",
- strerror(-fh), restored_fn );
- form_alert(1, emsg);
- exit(1); /* quit */
- } /* if */
- if( (fh = Fcreate( restored_fn, 0)) < 0 ) {
- char emsg[80];
- sprintf( emsg, "[1][%s|while creating %s][QUIT]",
- strerror(-fh), restored_fn );
- form_alert(1, emsg);
- exit(1); /* quit */
- } /* if */
- } /* if */
- if( (bytes_written = Fwrite(fh, file_size, data_buffer)) < 0 ) {
- char emsg[80];
- error = (int)bytes_written;
- sprintf( emsg, "[1][%s|while writing %s][QUIT]",
- strerror(-error), restored_fn );
- form_alert(1, emsg);
- exit(1); /* quit */
- } /* if */
-
- if( (error = Fclose(fh)) != 0 ) {
- char emsg[80];
- sprintf( emsg, "[1][%s|while trying to close %s][QUIT]",
- strerror(-error), restored_fn );
- form_alert(1, emsg);
- exit(1); /* quit */
- } /* if */
-
- } /* undelete_file() */
-
-
- /**************************************************************
- *
- * find next cluster in a chain of FAT entries ...
- *
- * FAT entries: 12-bit 16-bit meaning
- * ------ ------ -------
- * 000 0000 free cluster
- * 001 0001 shouldn't happen
- * 002 - FEF 0002 - 7FFF next cluster nr
- * 8000 - FFEF shouldn't happen
- * FF0 - FF7 FFF0 - FFF7 bad cluster
- * FF8 - FFF FFF8 - FFFF end of chain
- *
- * max nr clusters for 12 bit FAT = 4078
- *
- **************************************************************/
-
- PRIVATE WORD next_cluster( const WORD clust )
- {
- int index; /* index into FAT */
- WORD newclust; /* next cluster */
-
- /*** if nr clusters on disk > MAX_CLUSTERS use 16-bit FATs ***/
-
- if( bpbp->numcl > MAX_CLUSTERS ) {
- /*** 16-bit FATs ***/
- index = clust;
- newclust = FatBuffer[index] + (FatBuffer[index+1] << 8); /* byte swap */
- if( newclust >= 0xfff8 ) {
- return CHAIN_END;
- }
- else if( newclust >= 0x8000 )
- {
- /*** there is a file system problem if this happens ***/
- char emsg[128];
- sprintf(emsg, "[1][file system problem|bad cluster chain|"
- "at cluster %1d, value is %1d][QUIT]", (int)clust, (int)newclust );
- form_alert(1, emsg );
- exit(1); /* quit */
- } /* if */
- }
- else {
- /*** 12-bit FATs ***/
- index = clust + (clust >> 1);
- newclust = FatBuffer[index] + (FatBuffer[index+1] << 8); /* byte swap */
- if( clust & 1) { /* is clust odd ?? */
- newclust >>= 4;
- } /* if */
- newclust &= 0x0fff;
- if( newclust >= 0xff8 ) {
- return CHAIN_END;
- }
- else if( newclust >= 0x0ff0 )
- {
- /*** there is a file system problem if this happens ***/
- char emsg[128];
- sprintf(emsg, "[1][file system problem|bad cluster chain|"
- "at cluster %1d, value is %1d][QUIT]", (int)clust, (int)newclust );
- form_alert(1, emsg );
- exit(1); /* quit */
- } /* if */
- } /* if */
-
- return newclust;
-
- } /* next_cluster() */
-
-
- /********************************************************
- *
- * check names for a match.
- * fname in format 'nnnnnnnneee', ie 8 chars name + 3 chars extension
- * sname is a null terminated string.
- * match up to first directory separator (ie '\') in sname
- * return TRUE if match found, FALSE otherwise
- *
- ********************************************************/
-
- PRIVATE BOOL match( const char *sname, /* search match name */
- const char *fname /* file or directory name */
- )
- {
- const char *fext; /* file or dir extension */
-
- fext = fname + 8;
- while( fname < fext+3 ) {
- if( *fname == *sname ) {
- fname++;
- sname++;
- }
- else {
- /*** check why names differ ***/
- switch( *sname++ ) {
- case '.':
- if( (*fname == ' ') OR (fname == fext) ) {
- fname = fext;
- }
- else {
- return FALSE;
- } /* if */
- break;
- case '\\':
- case '\0':
- if( *fname == ' ' ) {
- return TRUE;
- } /* if */
- break;
- default:
- return FALSE;
- } /* switch */
- } /* if */
- } /* while */
- return TRUE;
- } /* match() */
-
-
- /*******************************
- *
- * swap bytes the bytes in a word argument
- *
- *******************************/
-
- PRIVATE WORD swap_word( const WORD word )
- {
- WORD r;
-
- ((char *)&r)[0] = ((char *)&word)[1];
- ((char *)&r)[1] = ((char *)&word)[0];
- return r;
-
- } /* swap_word() */
-
-
- PRIVATE LONG swap_long( const LONG l )
- {
- LONG r;
-
- ((char *)&r)[0] = ((char *)&l)[3];
- ((char *)&r)[1] = ((char *)&l)[2];
- ((char *)&r)[2] = ((char *)&l)[1];
- ((char *)&r)[3] = ((char *)&l)[0];
- return r;
-
- } /* swap_word() */
-
-
- /********************************************
- *
- * copy filename from directory entry to dta
- *
- ********************************************/
-
- PRIVATE void fnmcpy(char* d, const char *s)
- {
- int i; /* character counter */
- const char *extp; /* pointer to extension */
-
- extp = s+8;
-
- i = 8; /* copy up to 8 chars for name */
- while( (i > 0) AND ((unsigned)*s > ' ') ) { /* stop at '\0' or ' ' */
- *d++ = *s++;
- i--;
- } /* while */
-
- if( (unsigned)*extp > ' ' ) {
- *d++ = '.';
- i = 3; /* copy up to 3 chars for extension */
- while( (i > 0) AND ((unsigned)*extp > ' ') ) {
- *d++ = *extp++;
- i--;
- } /* while */
- } /* if */
- *d = '\0';
- } /* fnmcpy() */
-
-
-
- /************************* end of undel.c *************************/
-